package com.zw.utils;

import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @Author: ZhangWu
 * @DateTime: 2022/4/15 16:19
 * @Description: 类型数据转换工具
 */
public class CopyUtils {
    /**
     * 拷贝list
     * @param fromList 来源
     * @param clazz 拷贝后list的泛型
     * @param <T>
     * @return
     */
    public static <T> List<T> copyList(List fromList,Class<T> clazz){

        List<T> toList = new ArrayList<>();

        if (fromList != null && fromList.size() > 0) {
            for (Object fromObj : fromList) {
                try {
                    T t = clazz.newInstance();
                    BeanUtils.copyProperties(fromObj,t);
                    toList.add(t);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }
        }
        return toList;
    }
    /**
     * 拷贝一个对象
     * @param fromObj 来源
     * @param clazz 拷贝后list的泛型
     * @param <T>
     * @return
     */
    public static <T> T copyObj(Object fromObj,Class<T> clazz){

        if (fromObj != null) {
                try {
                T t = clazz.newInstance();
                BeanUtils.copyProperties(fromObj,t);
                return t;
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        return null;
    }
    /**
     * 任意对象拷贝相同字段值
     * @param s
     * @param t
     * @param <SOURCE>
     * @param <TARGET>
     */
    public static <SOURCE, TARGET> void copyValue(SOURCE s, TARGET t) {
        try {
            Map<String, Object> fieldNameAndValue = getFieldNameAndValue(s);
            Class clazz = Class.forName(t.getClass().getName());
            //根据Class对象获得属性 私有的也可以获得
            Field[] fields = clazz.getDeclaredFields();
            for (Field f : fields) {
                if (fieldNameAndValue.containsKey(f.getName())) {
                    f.setAccessible(true);
                    f.set(t, fieldNameAndValue.get(f.getName()));
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 获取对象的所有字段名和字段值
     *
     * @param object
     * @return
     */
    private static Map<String, Object> getFieldNameAndValue(Object object) {
        Map<String, Object> map = new HashMap<>();
        Class clazz = object.getClass();
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(object));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
}
